#include <my_header.h>

/* Usage: ./8_Bread_select_time*/
int main(int argc, char *argv[]){                                  
    int fd_read = open("write.pipe", O_RDONLY);
    int fd_write = open("read.pipe", O_WRONLY);
    ERROR_CHECK(fd_read, -1, "open read");
    ERROR_CHECK(fd_write, -1, "open write");
    printf("管道打开\n");

    char buf[60];
    fd_set set; // 构建初始化集合

    while(1)
    {
        FD_ZERO(&set);
        FD_SET(STDIN_FILENO, &set);
        FD_SET(fd_read, &set);

        int res_select = select(fd_read+1, &set, NULL, NULL, NULL);
        ERROR_CHECK(res_select, -1, "select");
        if(FD_ISSET(fd_read, &set))
        {
            bzero(buf,sizeof(buf));
            int read_num = read(fd_read, buf, sizeof(buf));
            if(read_num == 0)
            {
                // 数据已读完
                printf("对方已断开连接\n");
                break;
            }
            // 打印对方输出的数据
            printf("UserA: %s", buf);
        }
        if (FD_ISSET(STDIN_FILENO, &set)) {  // 检查标准输入是否准备好
            time_t now = time(NULL);  // 获取当前时间
            struct tm *tm_info = localtime(&now);  // 将当前时间转换为本地时间结构
            char time_str[26];  // 定义一个字符数组来存储格式化的时间字符串
            strftime(time_str, sizeof(time_str), 
                     "[%Y-%m-%d %H:%M:%S] ", tm_info);  // 格式化时间并存储在 time_str 中

            bzero(buf, sizeof(buf));  // 清空缓冲区，以确保没有残留数据
                                      // 开始输入数据
            int read_stdin = read(STDIN_FILENO, buf, sizeof(buf));  // 从标准输入读取用户输入
            if (read_stdin == 0) {  // 检查是否有输入
                break;  // 如果没有输入（EOF），则退出循环
            }

            // 发送带有时间戳的消息
            char message[100];  // 定义一个字符数组来存储最终要发送的消息
            snprintf(message, sizeof(message), 
                     "%s%s", time_str, buf);  // 将时间戳和用户输入的消息组合在一起
            write(fd_write, message, strlen(message) + 1);  // 通过管道发送组合后的消息，包括字符串结束符
        }
    }

    close(fd_read);
    close(fd_write);
    return 0;
}

#if 0
 #include <time.h>
  size_t strftime( char *str, size_t maxsize, 
                   const char *fmt, struct tm *time );


功能：函数按照参数fmt所设定格式将time类型的参数格式
化为日期时间信息，然后存储在字符串str中（至多maxsize 
个字符）。                                             

snprintf() 是 C 标准库中的一个函数，用于将格式化的
输出写入指定的字符数组中。其函数原型如下：
int snprintf(char *str, size_t size, const char *format, ...);
str：指向要写入的字符数组的指针。
size：要写入的最大字符数，包括终止的空字符 \0。
format：格式字符串，类似于 printf()，可以包含格式控制说明符（如 %s, %d）。
...：要格式化的额外参数。



#endif

#if 0
// 主函数  
int main() {  
    // 打开读取管道 "1.pipe"，以只读模式  
    int fd_read = open("1.pipe", O_RDONLY);  
    // 打开写入管道 "2.pipe"，以只写模式  
    int fd_write = open("2.pipe", O_WRONLY);  
    printf("管道打开 \n");  

    // 定义一个文件描述符集，用于 select 函数  
    fd_set set;  

    // 无限循环，直到手动退出  
    while (1) {  
        // 清空文件描述符集  
        FD_ZERO(&set);  
        // 将标准输入（键盘）加入文件描述符集  
        FD_SET(STDIN_FILENO, &set);  
        // 将读取管道的文件描述符加入文件描述符集  
        FD_SET(fd_read, &set);  

        // 监视文件描述符，等待输入  
        select(fd_read + 1, &set, NULL, NULL, NULL);  

        // 检查标准输入是否有数据可读  
        if (FD_ISSET(STDIN_FILENO, &set)) {  
            // 获取当前时间  
            time_t t = time(NULL);  
            // 将时间转换为字符串格式  
            char *time_str = ctime(&t);  
            // 获取时间字符串的长度  
            int len = strlen(time_str);  
            // 将时间字符串的长度写入写入管道  
            write(fd_write, &len, sizeof(int));  
            // 将时间字符串写入写入管道  
            write(fd_write, time_str, len);  

            // 定义一个缓冲区用于读取标准输入  
            char buf[60] = {0};  
            // 从标准输入读取数据  
            read(STDIN_FILENO, buf, sizeof(buf));  
            // 将读取到的数据写入写入管道  
            write(fd_write, buf, sizeof(buf));  
        }  

        // 检查读取管道是否有数据可读  
        if (FD_ISSET(fd_read, &set)) {  
            // 读取管道中时间字符串的长度  
            int len = 0;  
            read(fd_read, &len, sizeof(int));  
            // 定义一个缓冲区用于存储读取到的时间字符串  
            char time_buf[60] = {0};  
            // 读取时间字符串  
            read(fd_read, time_buf, len);  
            // 打印读取到的时间字符串  
            printf("%s", time_buf);  

            // 定义一个缓冲区用于读取管道中的其他数据  
            char buf[60] = {0};  
            // 从管道中读取数据  
            int ret = read(fd_read, buf, sizeof(buf));  
            // 如果读取到的数据长度为 0，表示管道已关闭，退出循环  
            if (ret == 0) {  
                break;  
            }  
            // 打印读取到的数据  
            printf("buf: %s \n", buf);  
        }  
    }  

    // 关闭读取和写入管道  
    close(fd_read);  
    close(fd_write);  
    return 0;  
}  

#endif
